<template>
    <div class="tnxel-query-table">
        <el-table ref="table"
            :data="records || []"
            :empty-text="emptyRecordText"
            :size="size"
            :border="border"
            :stripe="stripe"
            :row-key="rowKey"
            :tree-props="treeProps"
            :lazy="load !== undefined && load !== null"
            :load="load"
            :default-sort="defaultSort"
            :key="tableKey"
            :row-class-name="rowClassName"
            :default-expand-all="defaultExpandAll"
            :span-method="spanMethod"
            :max-height="maxHeight"
            @sort-change="sort"
            @selection-change="selectionChange"
            v-loading="querying">
            <slot></slot>
        </el-table>
        <tnxel-paged :value="paged" :change="query" :align="pagedAlign" :page-sizes="pagedSizes" :layout="pagedLayout"
            v-if="paged"/>
    </div>
</template>

<script>
import Paged from '../paged';

export default {
    components: {
        'tnxel-paged': Paged
    },
    name: 'TnxelQueryTable',
    props: {
        app: String,
        url: {
            type: String,
            required: true,
        },
        value: Object, // 查询参数
        size: String,
        border: {
            type: Boolean,
            default: true,
        },
        stripe: {
            type: Boolean,
            default: true,
        },
        pagedAlign: String,
        pagedSizes: Array,
        pagedLayout: String,
        success: Function,
        rowClassName: String,
        formatter: Function,
        init: Boolean,
        rowKey: [String, Function],
        treeProps: Object,
        load: Function,
        defaultExpandAll: Boolean,
        spanMethod: Function,
        maxHeight: [String, Number],
    },
    data() {
        return {
            params: this.getParams(this.value),
            records: null,
            querying: false,
            paged: null,
            tableKey: new Date().toString(),
        }
    },
    computed: {
        emptyRecordText() {
            if (this.querying) {
                return '加载中...';
            } else if (this.records === null) {
                return '尚未开始查询';
            } else {
                return '<空>';
            }
        },
        defaultSort() {
            let sortableColumnNames = [];
            if (this.$slots.default && this.$slots.default.length) {
                for (let column of this.$slots.default) {
                    if (column.componentOptions) {
                        let props = column.componentOptions.propsData;
                        if (props.prop && props.sortable === 'custom') {
                            sortableColumnNames.push(props.prop);
                        }
                    }
                }
            }
            if (sortableColumnNames.length) {
                if (this.paged && this.paged.orders && this.paged.orders.length) {
                    let fieldOrder = this.paged.orders[0];
                    let fieldName = fieldOrder.name;
                    if (sortableColumnNames.contains(fieldName)) {
                        return {
                            prop: fieldName,
                            order: fieldOrder.desc ? 'descending' : 'ascending',
                        };
                    }
                }
                if (this.params && this.params.orderBy) {
                    let array = this.params.orderBy.split(' ');
                    let fieldName = array[0];
                    if (sortableColumnNames.contains(fieldName)) {
                        return {
                            prop: fieldName,
                            order: (array[1] || 'asc').toLowerCase() === 'desc' ? 'descending' : 'ascending',
                        }
                    }
                }
            }
            return undefined;
        },
        defaultSortString() {
            if (this.defaultSort) {
                return this.defaultSort.prop + ' ' + this.defaultSort.order;
            }
            return undefined;
        },
    },
    watch: {
        value: {
            handler: function (value) {
                this.params = this.getParams(value);
            },
            deep: true,
        },
    },
    mounted() {
        if (this.init) {
            this.query();
        }
    },
    methods: {
        getParams(value) {
            return Object.assign({}, this.params, value); // 避免改动传入的参数对象
        },
        query(params) {
            if (typeof params === 'number') { // 参数为页码
                params = {pageNo: params};
            }
            if (typeof params === 'object') {
                // 指定了value属性，在页码变更时需要触发更新事件
                let pageNoChanged = this.params.pageNo !== params.pageNo;
                this.params = this.getParams(params);
                this.params.pageNo = this.params.pageNo || 1;
                if (pageNoChanged && this.value) {
                    this.$emit('input', this.params);
                }
            }

            this.records = null;
            this.querying = true;
            let vm = this;
            window.tnx.app.rpc.get(this.url, this.params).then(result => {
                vm.querying = false;
                if (Array.isArray(result)) {
                    vm.records = vm.format(result);
                } else {
                    vm.records = vm.format(result.records);
                    vm.paged = result.paged;
                }
                vm.tableKey = new Date().toString();
                if (vm.success) {
                    vm.success(vm.records, vm.paged);
                }
            });
        },
        format(records) {
            if (this.formatter) {
                return this.formatter(records);
            }
            return records;
        },
        sort(options) {
            if (options && options.prop && options.order) {
                this.params.orderBy = options.prop + (options.order === 'descending' ? ' desc' : '');
            } else {
                delete this.params.orderBy;
            }
            this.query(1);
        },
        selectionChange(selection) {
            this.$emit('selection-change', selection);
        },
        toggleRowExpansion(row, expanded) {
            this.$refs.table.toggleRowExpansion(row, expanded);
        },
    }
}
</script>
